/* @author: 	 Jeramie Hallyburton
 * @file:		 Game.java
 * @date:		 12/09/2011
 * @description: Holds all state data for current game
 */
package mobiledev.project3.spaceinvaders;

import game.spaceinvaders.R;

import java.util.ArrayList;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.Log;
import android.view.Window;
import android.view.WindowManager;

public class Game extends Activity {
	private static final String TAG = "Space Invaders";
	protected static final int START_GAME = 0;
	protected static final int CONTINUE_GAME = 1;
	
	private int score = 0;
	private int nColumns = 5;
	private int nRows = 6;
	
	public ArrayList<Ship> 		ships 		= new ArrayList<Ship>();
	public ArrayList<Shot> 		shotsFired 	= new ArrayList<Shot>();
	public ArrayList<Cannon> 	cannons 	= new ArrayList<Cannon>();
	
	//game sprites
	private Bitmap greenShip = null; 
	private Bitmap blueShip = null; 
	private Bitmap pinkShip = null; 
	
	
	//tracking variables
	private int totalShots = 0;
	private int hits = 0;
	private int currentLevel = 0;
	private boolean newLevel = true;
	private boolean speedIncreased = false;

	private long shotTime;
	private long shotDiff;
	
	private SpaceInvadersView siView;
	private int screenHeight;
	private int screenWidth;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
	    Log.d(TAG, "onCreate");
	    siView = new SpaceInvadersView(this);
	    greenShip = BitmapFactory.decodeResource(getResources(), R.drawable.greenship);
	    blueShip = BitmapFactory.decodeResource(getResources(), R.drawable.blueship);
	    pinkShip = BitmapFactory.decodeResource(getResources(), R.drawable.pinkship);
	    
	    int status = getIntent().getIntExtra( "STATUS", CONTINUE_GAME );
	    String flatShips = getPreferences(MODE_PRIVATE).getString( "SHIPS", "" );
	    
	    //check if a previous game exists in bundle
	    if( "".equals( flatShips ) )
	    	status = START_GAME;
	    
	    if( status == CONTINUE_GAME ) {
	    	
	    	shipsFromFlatString( flatShips );
	    	cannons.add( new Cannon( BitmapFactory.decodeResource(getResources(), R.drawable.cannon), getIntent().getIntExtra( "CANNONX", 0 ), getIntent().getIntExtra( "CANNONY", 0 ) ) );
	    	score = getPreferences(MODE_PRIVATE).getInt( "SCORE", 0 );
	    	currentLevel = getPreferences(MODE_PRIVATE).getInt( "LEVEL", 0 );
	    	totalShots = getPreferences(MODE_PRIVATE).getInt( "SHOTS", 0 );
	    	hits = getPreferences(MODE_PRIVATE).getInt( "HITS", 0 );
	    	speedIncreased = getPreferences(MODE_PRIVATE).getBoolean( "SPEED", false );
	    	setNewLevel(false);
	    } else {
		    startLevel();
			
			int screenWidth = 0;
			int screenHeight = 0;
			//create cannon to defend enemy ships
			cannons.add( new Cannon( BitmapFactory.decodeResource(getResources(), R.drawable.cannon), screenWidth / 2, screenHeight ) );
	    }
		
		siView = new SpaceInvadersView(this);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
	    setContentView(siView);
	    siView.requestFocus();
	}

	@Override
	protected void onPause() {
      super.onPause();
      Log.d(TAG, "onPause");
      Music.stop(this);

      // Save the current settings
      getPreferences(MODE_PRIVATE).edit().putString("SHIPS", shipsToFlatString()).commit();
      getPreferences(MODE_PRIVATE).edit().putInt("CANNONX", cannons.get(0).getX()).commit();
      getPreferences(MODE_PRIVATE).edit().putInt("CANNONY", cannons.get(0).getY()).commit();
      getPreferences(MODE_PRIVATE).edit().putInt("SCORE", score ).commit();
      getPreferences(MODE_PRIVATE).edit().putInt("LEVEL", currentLevel ).commit();
      getPreferences(MODE_PRIVATE).edit().putInt("SHOTS", totalShots ).commit();
      getPreferences(MODE_PRIVATE).edit().putInt("HITS", hits ).commit();
      getPreferences(MODE_PRIVATE).edit().putBoolean("SPEED", speedIncreased ).commit();
	}
	
	@Override
	protected void onResume() {
		super.onResume();
		Music.play(this, R.raw.ark);
	}
	
	public String shipsToFlatString() {
		String flat = "";
		
		for( Ship ship : ships ) {
			flat += ship.getX() + "," + ship.getY() + "," + ship.getSpeed().getXv() + "," + ship.getColor() + "|";
		}

		return flat;
	}
	
	public void shipsFromFlatString(String flat) {
		String[] shipsStr = flat.split( "\\|" );
		
		Ship temp = null;
		for( String ship : shipsStr ) {
			String[] props = ship.split( "\\," );
			if( props[3].equals( "green" ) ) {
				temp = new Ship( greenShip, Integer.parseInt( props[0]), Integer.parseInt( props[1] ), "green" );
				temp.getSpeed().setXv( Float.parseFloat( props[2]) );
				ships.add( temp );
			} else if( props[3].equals( "blue" ) ) {
				temp = new Ship( blueShip, Integer.parseInt( props[0]), Integer.parseInt( props[1] ), "blue" );
				temp.getSpeed().setXv( Float.parseFloat( props[2]) );
				ships.add( temp );
			} else if( props[3].equals( "pink" ) ) {
				temp = new Ship( pinkShip, Integer.parseInt( props[0]), Integer.parseInt( props[1] ), "pink" );
				temp.getSpeed().setXv( Float.parseFloat( props[2]) );
				ships.add( temp );
			}
		}
	}
	
	public void startLevel() {
		//reset draw variables
		newLevel = true;
		speedIncreased = false;
		currentLevel++;
		
				
		Ship temp = null;
		
		//create squadron of ships
		for( int i = 0; i < nColumns; i++ ) {
			for( int j = 0; j < nRows; j++ ) {
				if( j % 2 == 0 ) {
					temp = new Ship( greenShip, (int)( i * ( greenShip.getWidth() * 1.5 ) ), (int)( ( j - 2 ) * ( greenShip.getHeight() * 1.15 ) ), "green" );
					temp.getSpeed().setXv( (float) (temp.getSpeed().getXv() + currentLevel / 4 * 1.3) );
					ships.add( temp );
				}
				else if( j % 3 == 0 ) {
					temp = new Ship( blueShip, (int)( i * ( blueShip.getWidth() * 1.15 ) ), (int)( ( j - 2 ) * ( blueShip.getHeight() * 1.15 ) ), "blue" );
					temp.getSpeed().setXv( (float) (temp.getSpeed().getXv()  + currentLevel / 4 * 1.3) );
					ships.add( temp );
				} else {
					temp = new Ship( pinkShip, (int)( i * ( pinkShip.getWidth() * 1.05 ) ), (int)( ( j - 2 ) * ( pinkShip.getHeight() * 1.15 ) ), "pink" );
					temp.getSpeed().setXv( (float) (temp.getSpeed().getXv() + currentLevel / 4 * 1.3) );
					ships.add( temp );
				}
			}
		}
		
		if( currentLevel < 3 ) {
			nRows++;
			nColumns++;
		}

		
	}

	
	public ArrayList<Cannon> getCannons() {
		return this.cannons;
	}

	public void attemptShot() {
		//find the time between the last shot fired and now
		 shotDiff = System.currentTimeMillis() - shotTime;
		 
		 //allow 0.5 second between shots, prevents rapid firing
		 if( shotDiff > 500 ) {
			 for( Cannon cannon: cannons ) {
				 shotsFired.add( new Shot( BitmapFactory.decodeResource( getResources(), R.drawable.cannonshot ), cannon.getX(), cannon.getY()  ) );
				 setTotalShots(getTotalShots() + 1);
			 }
		 
			 //only update the shot time after a successful attempt
			 shotTime = System.currentTimeMillis();
		 } 
	}

	public void collisionCheck( Shot shot ) {
		//check for collision with a ship
		 for( Sprite ship : ships ) {
			 if( ( shot.getX() >= ship.getX() - ( ship.getBitmap().getWidth() / 2 ) && shot.getX() <= ship.getX() + ( ship.getBitmap().getWidth() / 2 ) ) &&
					 shot.getY() >= ship.getY() - ( ship.getBitmap().getHeight() / 2 ) && shot.getY() <= ship.getY() + ( ship.getBitmap().getHeight() / 2 ) ) {
				 ships.remove( ship );
				 
				 score += 400;
				 hits++;
				 
				 shotsFired.remove( shot );
			 }
		 }
		
	}
	
	public boolean checkGameOver() {
		for( Sprite ship : ships ) {
			 if( ship.getY() > screenHeight )
				 return true;
		 }
		return false;
	}

	public boolean checkNewLevel() {
		//if all ships are destroyed start new level
		 if ( ships.size() == 0 ) {
			 startLevel();
			 return true;
		 }
		 return false;
	}

	public void checkPowerUp() {
		if( score > 0 && score % 10000 == 0 ) {
			cannons.add( new Cannon( BitmapFactory.decodeResource(getResources(), R.drawable.cannon), 1, 1 ) );
		}
	}

	public int getScreenWidth() {
		return screenWidth;
	}

	public void setScreenWidth(int screenWidth) {
		this.screenWidth = screenWidth;
	}
	
	public int getScreenHeight() {
		return screenHeight;
	}

	public void setScreenHeight(int screenHeight) {
		this.screenHeight = screenHeight;
	}

	public int getTotalShots() {
		return totalShots;
	}

	public void setTotalShots(int totalShots) {
		this.totalShots = totalShots;
	}
	
	public int getCurrentLevel() {
		return currentLevel;
	}

	public void setCurrentLevel(int currentLevel) {
		this.currentLevel = currentLevel;
	}
	
	public int getScore() {
		return score;
	}

	public void setScore(int score) {
		this.score = score;
	}

	public boolean isNewLevel() {
		return newLevel;
	}

	public void setNewLevel(boolean newLevel) {
		this.newLevel = newLevel;
	}

	public int getHits() {
		return hits;
	}

	public void setHits(int hits) {
		this.hits = hits;
	}

	public void checkRemainingShips() {
		if( ships.size() < 4 ) {
			if( !speedIncreased ) {
				for( Ship ship : ships ) {
					ship.getSpeed().setXv( (float) (ship.getSpeed().getXv() * 4) );
				}
				speedIncreased = true;
			}
		}
		
		
	}

}
